import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:xreader/base/viewmodel/base_view_model.dart';
import 'package:xreader/logs/log.dart';

mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T>{
  void getUpdate(){
    //加载之后，在 setState,保险做法
     if(mounted){
       setState(() {

       });
     }
  }
}

typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(T controller);

abstract class BaseView<VM extends BaseViewModel> extends StatefulWidget{
  final GetControllerBuilder<VM>? builder;
  final Object? id;
  final String? tag;
  final bool autoRemove;
  final bool assignId;
  final Object Function(VM value)? filter;
  const BaseView({
      Key? key,
      this.builder,
      this.autoRemove = true,
      this.assignId = false,
      this.filter,
      this.tag,
      this.id
    }) : super(key: key);
  @override
  State<StatefulWidget> createState() => BaseViewState<VM>();
  Widget buildContent(BuildContext context,VM viewModel);
  void initState(BaseViewState<VM> state){

  }
  void dispose(BaseViewState<VM> state){

  }
  void didChangeDependencies(BaseViewState<VM> state){

  }
  void didUpdateWidget(BaseView oldWidget,BaseViewState<VM> state){

  }
  String get title => '';
  VM buildViewModel();
}

class BaseViewState<VM extends BaseViewModel> extends State<BaseView<VM>> with GetStateUpdaterMixin{
  VM? viewModel;// GetxController
  VoidCallback? _remove;
  Object? _filter;
  bool isNeedRemove = true;

  @override
  void initState() {
    super.initState();
    bool isRegistered = GetInstance().isRegistered<VM>(tag: widget.tag);
    Log.i("BaseViewState===> isRegistered=${isRegistered} widget.tag=${widget.tag}");
    //如果注册了,将 isNeedRemove 置为false
    if( isRegistered ){
      viewModel = Get.find<VM>(tag: widget.tag);
      isNeedRemove = false;
      viewModel?.onStart();
    }else{
      //没注册，调用 buildViewModel 实现方法注册
      viewModel = widget.buildViewModel();
      //初始化之后，塞进 GetInstance 中，用 tag 区分
      GetInstance().put<VM>(viewModel!,tag: widget.tag);
      isNeedRemove = true;//标记需要移除
    }
    //如果filter不为空，回调 filter,非空调用
    if(widget.filter != null){
      _filter = widget.filter!(viewModel!);
    }
    widget.initState.call(this);
  }

  void _subcribeToController() {
    _remove?.call();
    if(widget.id == null){
      viewModel?.addListener(_filter != null ? _filterUpdate : getUpdate);
    }
    if(widget.id != null){
      viewModel?.addListenerId(
        widget.id,
        _filter != null ? _filterUpdate : getUpdate
      );
    }
  }

  @override
  void dispose() {
    super.dispose();
    widget.dispose.call(this);
    if(isNeedRemove &&
        widget.autoRemove &&
        GetInstance().isRegistered<VM>(tag: widget.tag)
    ){
      GetInstance().delete<VM>(tag: widget.tag);
    }
    _remove?.call();
    viewModel = null;
    _remove = null;
    _filter = null;
  }
  void _filterUpdate(){
    var newFilter = widget.filter!(viewModel!);
    if(newFilter != _filter){
      _filter = newFilter;
      getUpdate();
    }
  }
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    widget.didChangeDependencies.call(this);
  }
  @override
  void didUpdateWidget(covariant BaseView<VM> oldWidget) {
    super.didUpdateWidget(oldWidget as BaseView<VM>);
    if(oldWidget.id != widget.id){
      _subcribeToController();
    }
    widget.didUpdateWidget.call(oldWidget,this);
  }

  @override
  Widget build(BuildContext context) {
    if(widget.builder == null){
      return widget.buildContent(context, viewModel!);
    }
    return widget.builder!(viewModel!);
  }

}